package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.CartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSkuVo;
import com.spzx.product.vo.SkuPriceVo;
import org.apache.poi.ss.formula.functions.Count;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: atguigu
 * @create: 2025-02-25 14:10
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RemoteProductService remoteProductService;


    /**
     * 返回用户购物车key
     *
     * @param userId
     * @return
     */
    public String getCartKey(Long userId) {
        //构建当前用户的购物车hash结构key
        return "user:cart:" + userId;
    }

    /**
     * 将商品加入到购物车 要求：单件商品购买上限99，购物车内商品种类上限50
     *
     * @param skuId  商品ID
     * @param skuNum 加购数量
     */
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //1.构建当前用户的购物车hash结构key 形式：user:cart:用户ID
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);
        String hashKey = skuId.toString();
        //2.创建购物车绑定hash操作对象 决定操作哪个用户购物车
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);

        //3.判断购物车是否已经有商品，如果有则数量相加 写回到Redis
        if (hashOps.hasKey(hashKey)) {
            CartInfo cartInfo = hashOps.get(hashKey);
            Integer skuNumMax = 99;
            int total = cartInfo.getSkuNum() + skuNum;
            cartInfo.setSkuNum(total > 99 ? skuNumMax : total);
            cartInfo.setUpdateTime(new Date());
            hashOps.put(hashKey, cartInfo);
        } else {
            //4.判断购物车是否没有商品，新建购物车商品对象 写回到Redis
            //4.1.判断购物车商品种类是否超过50种
            Long count = hashOps.size();
            if (++count > 50) {
                throw new RuntimeException("购物车商品种类超过50种");
            }
            //4.2 构建购物车对象
            CartInfo cartInfo = new CartInfo();
            //4.2.1 远程调用商品服务获取SKU商品信息
            ProductSkuVo productSkuVo = remoteProductService.getProductSku(skuId, SecurityConstants.INNER).getData();
            if (productSkuVo == null) {
                throw new ServiceException("远程调用商品服务获取SKU商品信息失败");
            }
            //4.2.2 为购物车商品对象属性赋值
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            cartInfo.setCartPrice(productSkuVo.getSalePrice());
            cartInfo.setSkuPrice(productSkuVo.getSalePrice());
            cartInfo.setSkuNum(skuNum > 99 ? 99 : skuNum);
            cartInfo.setThumbImg(productSkuVo.getThumbImg());
            cartInfo.setSkuName(productSkuVo.getSkuName());
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
            //4.2.3 写会到Redis
            hashOps.put(hashKey, cartInfo);
        }

    }

    /**
     * 查询当前用户购物车商品列表
     *
     * @return
     */
    @Override
    public List<CartInfo> cartList() {
        //1.构建当前用户的购物车hash结构key 形式：user:cart:用户ID
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);
        //2.创建购物车绑定hash操作对象 决定操作哪个用户购物车
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //3.获取hash结构中所有value
        List<CartInfo> cartInfoList = hashOps.values();
        //TODO : 远程调用商品服务获取SKU最新价格
        //4.按照购物车商品创建时间降序
        cartInfoList.sort((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()));
        return cartInfoList;
    }

    /**
     * 删除购物车中指定商品
     *
     * @param skuId
     */
    @Override
    public void deleteCart(Long skuId) {
        //1.构建当前用户的购物车hash结构key 形式：user:cart:用户ID
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);
        //2.创建购物车绑定hash操作对象 决定操作哪个用户购物车
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        String hashKey = skuId.toString();
        hashOps.delete(hashKey);
    }

    /**
     * 修改购物车商品选中状态
     *
     * @param skuId     商品ID
     * @param isChecked 1：选中  0：取消选中
     * @return
     */
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //1.构建当前用户的购物车hash结构key 形式：user:cart:用户ID
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);
        //2.创建购物车绑定hash操作对象 决定操作哪个用户购物车
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        String hashKey = skuId.toString();
        //3.查询购物车中商品信息
        CartInfo cartInfo = hashOps.get(hashKey);
        if (cartInfo != null) {
            cartInfo.setIsChecked(isChecked);
            hashOps.put(hashKey, cartInfo);
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        //1.构建当前用户的购物车hash结构key 形式：user:cart:用户ID
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);
        //2.创建购物车绑定hash操作对象 决定操作哪个用户购物车
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //3.获取所有购物车中商品列表
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            for (CartInfo cartInfo : cartInfoList) {
                cartInfo.setIsChecked(isChecked);
                cartInfo.setUpdateTime(new Date());
                hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
            }
        }
    }


    @Override
    public void clearCart() {
        //1.构建当前用户的购物车hash结构key 形式：user:cart:用户ID
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);
        redisTemplate.delete(cartKey);
    }

    /**
     * 获取购物车中用户选中商品列表
     *
     * @return
     */
    @Override
    public List<CartInfo> getCartCheckedList() {
        //1.构建当前用户的购物车hash结构key 形式：user:cart:用户ID
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);
        //2.创建购物车绑定hash操作对象 决定操作哪个用户购物车
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            //3.过滤出选中商品 Stream流过滤
            List<CartInfo> list = cartInfoList.stream()
                    .filter(cartInfo -> cartInfo.getIsChecked().intValue() == 1)
                    .collect(Collectors.toList());
            return list;
        }
        return null;
    }

    /**
     * 更新购物车中选中商品最新价格
     *
     * @param userId
     * @return
     */
    @Override
    public Boolean updateCartPrice(Long userId) {
        //1.构建当前用户的购物车hash结构key 形式：user:cart:用户ID
        String cartKey = this.getCartKey(SecurityUtils.getUserId());
        //2.创建购物车绑定hash操作对象 决定操作哪个用户购物车
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        //3.过滤出选中商品，获取最新价格，完成更新
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList
                    .stream()
                    //过滤出，选中状态商品
                    .filter(cartInfo -> cartInfo.getIsChecked().intValue() == 1)
                    .forEach(cartInfo -> {
                        //远程调用商品服务获取最新价格
                        R<SkuPriceVo> r = remoteProductService.getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER);
                        if (R.SUCCESS == r.getCode()) {
                            SkuPriceVo skuPriceVo = r.getData();
                            cartInfo.setSkuPrice(skuPriceVo.getSalePrice());
                            hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
                        }
                    });
        }
        return true;
    }

    /**
     * 删除用户购物车列表中选中商品列表
     *
     * @param userId
     */
    @Override
    public void deleteCartCheckedList(Long userId) {
        //1.构建当前用户的购物车hash结构key 形式：user:cart:用户ID
        String cartKey = this.getCartKey(SecurityUtils.getUserId());
        //2.创建购物车绑定hash操作对象 决定操作哪个用户购物车
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        //3.过滤出选中商品，获取最新价格，完成更新
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList
                    .stream()
                    //过滤出，选中状态商品
                    .filter(cartInfo -> cartInfo.getIsChecked().intValue() == 1)
                    //映射获取商品SKUID
                    .map(CartInfo::getSkuId)
                    //遍历删除 选中商品
                    .forEach(skuId -> hashOps.delete(skuId.toString()));
        }
    }
}
